package com.symaster.common.geom.entity;

import com.symaster.common.geom.Geom;
import com.symaster.common.geom.util.PointUtil;

/**
 * @author yinmiao
 * @version 2022-08-23 19:15
 */
public class Circle implements Geom, Cloneable {

    private static final long serialVersionUID = -123451623014231324L;
    private Point center;
    private Double radius;

    public Circle() {
    }

    public Circle(Point center, Double radius) {
        this.center = center;
        this.radius = radius;
    }

    public Point getCenter() {
        return center;
    }

    public void setCenter(Point center) {
        this.center = center;
    }

    public Double getRadius() {
        return radius;
    }

    public void setRadius(Double radius) {
        this.radius = radius;
    }

    public Double getDiameter() {
        if (radius == null) {
            return null;
        }
        return radius * 2.0;
    }

    public Polygon toPolygon(double threshold) {
        int v = (int) (360 / threshold);

        double[] xPoints = new double[v];
        double[] yPoints = new double[v];
        double y = center.getY();
        double v1 = y - radius;
        Point p1 = new Point(center.getX(), v1);
        for (int i = 0; i < v; i++) {
            Point point = PointUtil.rotateTransform(p1, center, threshold * i);
            xPoints[i] = point.x;
            yPoints[i] = point.y;
        }

        return new Polygon(xPoints, yPoints);
    }

    @Override
    public String toString() {
        return "Circle{" +
                "center=" + center +
                ", radius=" + radius +
                '}';
    }

    @Override
    public boolean isEmpty() {
        return center == null || radius == null;
    }

    @Override
    public void scaleTransform(Point center, double scale) {
    }

    @Override
    public void rotateTransform(Point center, double angle) {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        this.center = PointUtil.rotateTransform(this.center, center, angle);
    }

    @Override
    public void translate(Vector vector) {
        translate(vector.getX(), vector.getY());
    }

    @Override
    public void translate(double x, double y) {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        this.center.setX(this.center.getX() + x);
        this.center.setY(this.center.getY() + y);
    }

    @Override
    public void move(Point dst) {
        move(dst.x, dst.y);
    }

    @Override
    public void move(double x, double y) {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        this.center.setX(x);
        this.center.setY(y);
    }

    @Override
    public double height() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return radius * 2;
    }

    @Override
    public double width() {
        return height();
    }

    @Override
    public Polygon toPolygon() {
        return toPolygon(1);
    }

    @Override
    public double area() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return 0;
    }

    @Override
    public Point center() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return center;
    }

    @Override
    public Point point() {
        return new Point(minX(), minY());
    }

    @Override
    public double minX() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return center.x - radius;
    }

    @Override
    public double minY() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return center.y - radius;
    }

    @Override
    public double maxX() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return center.x + radius;
    }

    @Override
    public double maxY() {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }
        return center.y + radius;
    }

    @Override
    public void map(GMap gMap) {
        if (isEmpty()) {
            throw new IllegalArgumentException();
        }

        center.x = gMap.handler(center.x);
        center.y = gMap.handler(center.y);
        radius = gMap.handler(radius);
    }

    @Override
    public Circle clone() {
        try {
            Circle clone = (Circle) super.clone();
            clone.center = new Point(this.center.getX(), this.center.getY());
            clone.radius = this.radius;
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}
